package cn.mujiankeji.mbrowser.工具.操作



/**
 *
 * @date ：Created in 2020.10.27
 */
object 简易文本匹配器 {
    fun parser(con: String, rule: String, abs: Boolean): Boolean {

        // 含有通配符
        var tp = rule.contains("*")
        if (!tp) {
            // 踢掉内容比规则短的
            if (con.length < rule.length) return false
        }

        // 符号通配符 ^
        tp = tp || rule.contains("^")

        // 不含通配符
        return if (!tp) {
            if (abs) {
                if (rule.length > con.length) false else rule == con.substring(0, rule.length)
            } else {
                con.contains(rule)
            }
        } else {
            匹配(con, rule, abs)
        }
    }

    /**
     *
     * @param con
     * @param rule
     * @param abs 从0开始匹配
     * @return
     */
    fun 匹配(con: String, rule: String, abs: Boolean): Boolean {

        // 取规则
        val nextRule = nextRule(rule) ?: return true
        // 匹配完毕即成功，返回NULL对象为失败 这些返回空文本对象
        if (nextRule == "*") {
            return 匹配(con, rule.substring(1), false)
        }

        // 符号通配
        return if (nextRule == "^") {
            p6(con, rule.substring(1), abs)
        } else {
            // 绝对匹配
            if (abs) {
                if (con.length >= nextRule.length) {
                    val cc = con.substring(0, nextRule.length)
                    // 匹配则执行下一条匹配
                    if (cc == nextRule) {
                        if (匹配(
                                con.substring(nextRule.length),
                                rule.substring(nextRule.length),
                                true
                            )
                        ) return true

                        // String xcon = p(con.substring(nextRule.length()),rule.substring(nextRule.length()),true);
                        // 内容不为空，就是匹配成功
                        //if (xcon != null) return con.substring(0,nextRule.length()) + xcon;
                    }
                }

                // 到这里均为失败
                false
            } else {
                var pos = con.indexOf(nextRule)
                while (pos != -1) {
                    pos += nextRule.length
                    if (匹配(
                            con.substring(pos),
                            rule.substring(nextRule.length),
                            true
                        )
                    ) return true

                    //String xcon = p(con.substring(pos+nextRule.length()),rule.substring(nextRule.length()),true);

                    // 成功返回，否则继续循环
                    //if (xcon != null) return con.substring(0,nextRule.length() + pos) + xcon;
                    pos = con.indexOf(nextRule, pos)
                }
                false
            }
        }
    }

    /**
     * ^ 专用匹配
     * @param con
     * @param rule
     * @param abs
     * @return
     */
    fun p6(con: String, rule: String, abs: Boolean): Boolean {
        if (con.length < 1) return false

        // 首个字符就必须是，匹配通过就执行下一条匹配
        if (abs) {
            return p6t(con, rule, con.substring(0, 1).toCharArray()[0])
        } else {
            val cons = con.toCharArray()
            for (i in cons.indices) {
                if (p6t(String(cons, i, cons.size - i), rule, cons[i])) return true
            }
        }
        return false
    }

    fun p6t(con: String, rule: String, word: Char): Boolean {
        val xt = "/:=+-&?.".toCharArray()
        for (c in xt) {
            if (c == word) {
                return if (c == xt[0] && con.length > 1 && con.substring(1, 2) == "/") {
                    匹配(con.substring(2), rule, true)
                } else {
                    匹配(con.substring(1), rule, true)
                }
            }
        }
        return false
    }

    // 读取下一个规则  通配符 ^ * 以及非通配符
    fun nextRule(rule: String): String? {
        val fh = "*^".toCharArray()
        val value = rule.toCharArray()
        val builder = StringBuilder()
        for (i in value.indices) {
            // * 或^
            for (c in fh) {
                if (value[i] == c) {
                    return if (builder.length > 0) {
                        builder.toString()
                    } else {
                        c.toString()
                    }
                }
            }
            builder.append(value[i])
        }
        return if (builder.length == 0) null else builder.toString() // 失败返回空
    }
}